/*
 * Copyright (C) 2012 Santiago Valdarrama
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package com.yuanmei.stockeyes.data;

import java.math.BigDecimal;
import java.util.HashMap;

import android.app.SearchManager;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.provider.BaseColumns;
import android.util.Log;

import com.yuanmei.stockeyes.artifacts.Constants;
import com.yuanmei.stockeyes.artifacts.Extensions;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import financedata.historicalquotes.HistoricalQuote;


//import android.util.Log;

public class StockInfoDatabase {

    public final static String DATABASE_NAME = "StockInfo";
    public final static String LOG_TAG = "StockInfoDatabase";

    private final static String TABLE_STOCK_SEARCH = "stock_search";


    public final static String KEY_STOCK_SEARCH_CODE   = "code";
    public final static String KEY_STOCK_SEARCH_NAME   = "name";
    public final static String KEY_STOCK_SEARCH_NAMEPY = "namepy";
    public final static String KEY_STOCK_SEARCH_MARKET = "market";
    public final static String KEY_STOCK_SEARCH_M_CODE = "m_code";
    public final static String KEY_STOCK_SEARCH_SUGGESTION = "suggestion";

    private static HashMap<String, String> searchContentProviderColumnMap;

    private StockInfoOpenHelper mStockInfoOpenHelper;

    static {
        StockInfoDatabase.searchContentProviderColumnMap = buildSearchContentProviderColumnMap();
    }

    public StockInfoDatabase(Context context) {
        
        StockInfoOpenHelper.ChkIfNeedCopyDbFile(context);
        
        this.mStockInfoOpenHelper = new StockInfoOpenHelper(context);
 
    }
 

    public Cursor getStockSearch(String symbol) {
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();

        builder.setTables(TABLE_STOCK_SEARCH);
        String[] columns = {
                KEY_STOCK_SEARCH_CODE,
                KEY_STOCK_SEARCH_NAME,
                KEY_STOCK_SEARCH_MARKET,
                KEY_STOCK_SEARCH_M_CODE};

        String selection = KEY_STOCK_SEARCH_CODE + " = ?";

        return builder.query(getReadableDatabase(), columns, selection, new String[] { symbol }, "", "", "");
    }
 
    public Cursor search(String query, String[] columns) {
        // boolean restrictSearchToNASDAQ = Constants.COMPILING_LITE_VERSION;
        //boolean restrictSearchToNASDAQ = false;

        //String exchangeSelection = "";

        String selection = KEY_STOCK_SEARCH_NAMEPY + " LIKE " + "'" + query + "%'";

        //String[] selectionArgs;
        
        //selectionArgs = new String[] { query + "*" };

        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(TABLE_STOCK_SEARCH);
        builder.setProjectionMap(StockInfoDatabase.searchContentProviderColumnMap);

        try{
            //String buildQuery= builder.buildQuery( columns, selection, null, null, null, null, null);
            Cursor cursor = builder.query(getReadableDatabase(), columns, selection, null, null, null, null);
            if (cursor == null) {
                return null;
            }
            else if (!cursor.moveToFirst()) {
                cursor.close();
                return null;
            }
            return cursor;
        }
        catch (Exception e) {
            return null;
        }
    }

    private String getServerBaseUrl() {
        return "http://45.78.36.245:8080/index.php";
    }

    private long getServerCodeUpdateTimeStamp(Context context) {
        try {
            String req_url = getServerBaseUrl() + "/stock/CodesModifedTime" ;
            String response = Extensions.getJSONFromUrl(req_url, 300 * 1000);
            JSONObject responseJSON = new JSONObject(response);
            return  responseJSON.getLong("CodesModifedTime");
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(LOG_TAG, "", e);
        }
        return 0L;
    }

    private boolean updateStockInfoDataBase() {

        boolean update_suceess = false;
        SQLiteDatabase database = mStockInfoOpenHelper.getWritableDatabase();
        try {
            database.beginTransaction();
            String req_url = getServerBaseUrl() + "/stock/Codes";
            String response = Extensions.getJSONFromUrl(req_url, 300 * 1000);
            JSONArray json_arrays = new JSONArray(response);
            ContentValues values = new ContentValues();
            int insert_cnts = 0;
            for (int i = 0; i < json_arrays.length(); i++) {
                JSONArray entry     = new JSONArray(json_arrays.getString(i));
                int stock_code      = entry.getInt(0);
                String stock_name   = entry.getString(1);
                String stock_namepy = entry.getString(2);
                String market_prfeix;
                int market;
                if ((stock_code >= 1000000 && stock_code <= 1999999)) {
                    market = 1;
                    if ((stock_code >= 1600000 && stock_code <= 1600999)
                            || (stock_code >= 1601000 && stock_code <= 1601999)
                            || (stock_code >= 1603000 && stock_code <= 1603999)
                            ) { // ShangHai A stock
                        market_prfeix = "sh";
                    } else {// ShangHai Market Index
                        market_prfeix = "^sh";
                    }
                } else if (stock_code >= 2000000 && stock_code <= 2999999) {
                    market = 2;
                    if ((stock_code >= 2000000 && stock_code <= 2009999)
                            || (stock_code >= 2300000 && stock_code <= 2300999)) {
                        // ShengZheng A stock
                        market_prfeix = "sz";
                    } else { // ShengZheng Market Index
                        market_prfeix = "^sz";
                    }
                } else {
                    Log.w(LOG_TAG, "Warning: not support stock code=" + stock_code);
                    continue;
                }
                String m_code = String.valueOf(stock_code).substring(1);
                String code = market_prfeix + m_code;
                String suggestion = stock_name + "    "+ m_code + "    " + stock_namepy;

                values.clear();
                values.put(KEY_STOCK_SEARCH_CODE, code);
                values.put(KEY_STOCK_SEARCH_NAME, stock_name);
                values.put(KEY_STOCK_SEARCH_NAMEPY, stock_namepy);
                values.put(KEY_STOCK_SEARCH_MARKET, market);
                values.put(KEY_STOCK_SEARCH_M_CODE, m_code);
                values.put(KEY_STOCK_SEARCH_SUGGESTION, suggestion);
                database.insertWithOnConflict(TABLE_STOCK_SEARCH, null, values, SQLiteDatabase.CONFLICT_REPLACE);
                insert_cnts++;
            }
            database.setTransactionSuccessful();
            //Log.d(LOG_TAG, "DBG: Insert codes count=" + insert_cnts);
            update_suceess = true;
        } catch (Exception e) {
            Log.e(LOG_TAG, "update StockInfo error=" + e);
            e.printStackTrace();
            update_suceess = false;
        } finally {
            database.endTransaction();
        }
        return update_suceess;
    }


    public void checkAndUpdateStockInfo(Context context) {

        long local_update_ts = context.getSharedPreferences(Constants.PREFERENCES,
                Context.MODE_PRIVATE).getLong(Constants.PREFERENCE_STOCKINFO_UPDATE_TS, 0);
        long svr_update_ts = getServerCodeUpdateTimeStamp(context);
        if (svr_update_ts <= 0) {
            return;
        }
        if (local_update_ts < svr_update_ts) {
            if (updateStockInfoDataBase()) {
                Log.d(LOG_TAG, "update stock info code base succ");
                context.getSharedPreferences(Constants.PREFERENCES, Context.MODE_PRIVATE)
                        .edit().putLong(Constants.PREFERENCE_STOCKINFO_UPDATE_TS, svr_update_ts)
                        .apply();
            } else {
                Log.d(LOG_TAG, "update stock info code base failure");
            }
        }
    }

    private SQLiteDatabase getReadableDatabase() {
        return this.mStockInfoOpenHelper.getReadableDatabase();
    }

    private static HashMap<String, String> buildSearchContentProviderColumnMap() {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put(BaseColumns._ID, KEY_STOCK_SEARCH_CODE + " AS " + BaseColumns._ID);

        map.put(SearchManager.SUGGEST_COLUMN_TEXT_1, KEY_STOCK_SEARCH_SUGGESTION + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_1);
        //map.put(SearchManager.SUGGEST_COLUMN_TEXT_2, "(" + KEY_STOCK_SEARCH_M_CODE  + "  ||  " + KEY_STOCK_SEARCH_NAMEPY  +  ")" + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_2);
        map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,  KEY_STOCK_SEARCH_CODE + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
        //map.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,  KEY_STOCK_SEARCH_CODE + " AS " + SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
        return map;
    }

}
